#pragma once
#include<queue>
#include<iostream>
#include<cstdio>
#include<pthread.h>
using namespace std;
template<class T>
class BlockQueue
{
    static const int defaultnum=10;
public:
    BlockQueue(int num=defaultnum)
    :maxnum(num)
    {
        pthread_mutex_init(&mutex_,nullptr);
        pthread_cond_init(&c_cond,nullptr);
        pthread_cond_init(&p_cond,nullptr);
    }

    T Pop()
    {
        pthread_mutex_lock(&mutex_);
        while(q.size()==0) //若阻塞队列为0.进入等待,同时叫生产者进行生产
        {
            pthread_cond_wait(&c_cond,&mutex_);
        }
        T tmp=q.front();
        q.pop();
        pthread_cond_signal(&p_cond);
        pthread_mutex_unlock(&mutex_);
        return tmp;
    }

    void push(const T &num)
    {
        pthread_mutex_lock(&mutex_);
        while(q.size()==maxnum)//阻塞队列满了，进入等待，同时叫消费者来消费
        {
            pthread_cond_wait(&p_cond,&mutex_);
        }
        q.push(num);
        pthread_cond_signal(&c_cond);
        pthread_mutex_unlock(&mutex_);
    }

    ~BlockQueue()
    {
        pthread_mutex_destroy(&mutex_);
        pthread_cond_destroy(&c_cond);
        pthread_cond_destroy(&p_cond);
    }
private:
    queue<T> q;
    int maxnum;
    pthread_mutex_t mutex_;
    pthread_cond_t c_cond;//消费者条件变量
    pthread_cond_t p_cond;//生产者
};